﻿using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;

namespace DbUpdateManageSql
{
    /// <summary>
    /// 获取Table 帮助类
    /// </summary>
    public class TableHelper
    {
        public static List<DbTable> GetDbTables(string connectionString, string tables = null)
        {

            if (!string.IsNullOrEmpty(tables))
            {
                tables = $" and obj.name in ('{tables.Replace(",", "','")}')";
            }
            #region SQL 
            string sql = @"SELECT
									obj.name tablename,
									schem.name schemname,
									idx.rows,
									CAST
									(
										CASE 
											WHEN (SELECT COUNT(1) FROM sys.indexes WHERE object_id= obj.OBJECT_ID AND is_primary_key=1) >=1 THEN 1
											ELSE 0
										END 
									AS BIT) HasPrimaryKey   ,ext.value Remark                                        
									from  sys.objects obj 
									INNER JOIN  dbo.sysindexes idx on obj.object_id=idx.id and idx.indid<=1
									INNER JOIN  sys.schemas schem ON obj.schema_id=schem.schema_id
									LEFT JOIN sys.extended_properties ext on  obj.object_id=ext.major_id and ext.minor_id<1 
									where type='U' AND obj.name !='sysdiagrams'  " + tables + " 	order by obj.name";
            #endregion
            DataTable dt = DbHelperSql.GetDataTable(sql);
            return dt.Rows.Cast<DataRow>().Select(row => new DbTable
            {
                TableName = row.Field<string>("tablename"),
                SchemaName = row.Field<string>("schemname"),
                Rows = row.Field<int>("rows"),
                HasPrimaryKey = row.Field<bool>("HasPrimaryKey"),
                Remark = row.Field<string>("Remark") == null ? row.Field<string>("tablename") : row.Field<string>("Remark"),
            }).ToList();
        }
        public static List<DbColumn> GetDbColumns(string connectionString, string tableName, string schema = "dbo")
        {
            #region SQL
            string sql = @"
                                    WITH indexCTE AS
                                    (
	                                    SELECT 
                                        ic.column_id,
                                        ic.index_column_id,
                                        ic.object_id    
                                        FROM  sys.indexes idx
                                        INNER JOIN sys.index_columns ic ON idx.index_id = ic.index_id AND idx.object_id = ic.object_id
                                        WHERE  idx.object_id =OBJECT_ID(@tableName) AND idx.is_primary_key=1
                                    )
                                    select
									colm.column_id ColumnID,
                                    CAST(CASE WHEN indexCTE.column_id IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey,
                                    colm.name ColumnName,
                                    systype.name DbType,
                                    colm.is_identity IsIdentity,
                                    colm.is_nullable IsNullable,
                                    cast(colm.max_length as int) ByteLength,
                                    (
                                        case 
                                            when systype.name='nvarchar' and colm.max_length>0 then colm.max_length/2 
                                            when systype.name='nchar' and colm.max_length>0 then colm.max_length/2
                                            when systype.name='ntext' and colm.max_length>0 then colm.max_length/2 
                                            else colm.max_length
                                        end
                                    ) CharLength,
                                    cast(colm.precision as int) Precision,
                                    cast(colm.scale as int) Scale,
                                    prop.value Remark
                                    from sys.columns colm
                                    inner join sys.types systype on colm.system_type_id=systype.system_type_id and colm.user_type_id=systype.user_type_id
                                    left join sys.extended_properties prop on colm.object_id=prop.major_id and colm.column_id=prop.minor_id
                                    LEFT JOIN indexCTE ON colm.column_id=indexCTE.column_id AND colm.object_id=indexCTE.object_id                                        
                                    where colm.object_id=OBJECT_ID(@tableName)
                                    order by colm.column_id";
            #endregion
            SqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, 100) { Value = string.Format("{0}.{1}", schema, tableName) };
            DataTable dt = DbHelperSql.GetDataTable(sql, param);
            return dt.Rows.Cast<DataRow>().Select(row => new DbColumn()
            {
                ColumnId = row.Field<int>("ColumnID"),
                IsPrimaryKey = row.Field<bool>("IsPrimaryKey"),
                ColumnName = row.Field<string>("ColumnName"),
                DbType = row.Field<string>("DbType"),
                IsIdentity = row.Field<bool>("IsIdentity"),
                IsNullable = row.Field<bool>("IsNullable"),
                ByteLength = row.Field<int>("ByteLength"),
                CharLength = row.Field<int>("CharLength"),
                Scale = row.Field<int>("Scale"),
                Remark = row["Remark"].ToString().Equals("") ? row["ColumnName"].ToString() : row["Remark"].ToString()
            }).ToList();
        }


        //public static DataTable GetDataTable(string connectionString, string commandText, params SqlParameter[] parms)
        //{
        //    using (SqlConnection connection = new SqlConnection(connectionString))
        //    {
        //        SqlCommand command = connection.CreateCommand();
        //        command.CommandText = commandText;
        //        command.Parameters.AddRange(parms);
        //        SqlDataAdapter adapter = new SqlDataAdapter(command);

        //        DataTable dt = new DataTable();
        //        adapter.Fill(dt);

        //        return dt;
        //    }
        //}
    }

}
